﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Castle.Services.Transaction;
using Meqs.Entity;
using Meqs.Entity.Parameters;
using Meqs.Logic.Interface;

namespace Meqs.Logic.Implement
{
    [Transactional]
    public class StuCauseEvalSubmitRecordLogic : CommonLogic<StuCauseEvalSubmitRecord, int>, IStuCauseEvalSubmitRecordLogic
    {
        private ISchoolInfoLogic _schoolLogic;
        private IStuCauseEvalListLogic _selLogic;
        private IStuCauseEvalDetailLogic _sdLogic;
        private IStuCauseEvalRemarkLogic _srLogic;
        private IStuCauseEvalHistoryLogic _shLogic;
        private IStuCausePersonCatchLogic _spcLogic;
        private IStuCausePersonTypeCatchLogic _sptcLogic;
        private IStuCauseEvalPersonItemCatchLogic _spicLogic;
        private IStuCauseEvalItemLogic _siLogic;
        public StuCauseEvalSubmitRecordLogic(ISchoolInfoLogic schoolLogic,
                                        IStuCauseEvalListLogic selLogic,
                                        IStuCauseEvalDetailLogic sdLogic,
                                        IStuCauseEvalRemarkLogic srLogic,
                                        IStuCauseEvalHistoryLogic shLogic,
                                        IStuCausePersonCatchLogic spcLogic,
                                        IStuCausePersonTypeCatchLogic sptcLogic,
                                        IStuCauseEvalPersonItemCatchLogic spicLogic,
                                        IStuCauseEvalItemLogic siLogic)
        {
            _schoolLogic = schoolLogic;
            _selLogic = selLogic;
            _sdLogic = sdLogic;
            _srLogic = srLogic;
            _shLogic = shLogic;
            _spcLogic = spcLogic;
            _sptcLogic = sptcLogic;
            _spicLogic = spicLogic;
            _siLogic = siLogic;
        }
        #region Implementation of ICommonLogic<StuCauseEvalSubmitRecord, int>

        /// <sammury>
        /// 创建对象
        /// </sammury>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int Create(StuCauseEvalSubmitRecord entity)
        {
            return CreateObject(entity);
        }

        /// <sammury>
        /// 更新对象
        /// </sammury>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int Update(StuCauseEvalSubmitRecord entity)
        {
            return UpdateObject(entity);
        }

        /// <summary>
        /// 删除对象
        /// </summary>
        /// <param name="entityId"></param>
        /// <returns></returns>
        public int Delete(int entityId)
        {
            return DeleteObject(entityId);
        }

        /// <summary>
        /// 删除所有对象
        /// </summary>
        /// <returns></returns>
        public int DeleteAll()
        {
            return DeleteAllObject();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="entityId"></param>
        /// <returns></returns>
        public StuCauseEvalSubmitRecord FindById(int entityId)
        {
            return FindObjectById(entityId);
        }

        /// <summary>
        /// 检索对象数量
        /// </summary>
        /// <returns></returns>
        public int FindCount()
        {
            return FindObjectByCount();
        }

        /// <sammury>
        /// 检索对象
        /// </sammury>
        public IList<StuCauseEvalSubmitRecord> FindAll()
        {
            return FindAllObject();
        }

        /// <summary>
        /// 检索对象数量
        /// </summary>
        /// <returns></returns>
        public int FindCount(Hashtable table)
        {
            return FindObjectByCount(table);
        }

        /// <sammury>
        /// 检索对象
        /// </sammury>
        public IList<StuCauseEvalSubmitRecord> FindAll(Hashtable table)
        {
            return FindObject(table);
        }

        #endregion

        #region Implementation of IStuCauseEvalSubmitRecordLogic

        /// <summary>
        /// 获取学分评价提交记录
        /// </summary>
        /// <param name="clsID"></param>
        /// <param name="causeID"></param>
        /// <param name="reportType"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <param name="schoolYear"></param>
        /// <param name="term"></param>
        /// <param name="schoolMark"></param>
        /// <returns></returns>
        public StuCauseEvalSubmitRecord GetRecordByCls(int clsID, int causeID, int reportType, int year, int month, int? schoolYear, int? term, string schoolMark)
        {
            try
            {
                Hashtable ht = new Hashtable();
                ht.Add("SchoolMark", schoolMark);
                ht.Add("ClsID", clsID);
                ht.Add("CauseID", causeID);
                ht.Add("ReportDate", new DateTime(year, month, 1));
                ht.Add("ReportType", reportType);
                ht.Add("SchoolYear", schoolYear);
                ht.Add("Term", term);
                return FindCustomerByID<StuCauseEvalSubmitRecord>("StuCauseEvalSubmitRecord.GetRecordByCls", ht);
            }
            catch (Exception)
            {
                return null;
            }
        }

        /// <summary>
        /// 保存记录
        /// </summary>
        /// <param name="list"></param>
        /// <param name="causeID"></param>
        /// <param name="clsID"></param>
        /// <param name="reportType"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <param name="schoolYear"></param>
        /// <param name="term"></param>
        /// <param name="teacherID"></param>
        /// <param name="schoolMark"></param>
        /// <returns></returns>
        [Transaction(TransactionMode.Supported)]
        public bool SaveOrUpdateRecord(IList<Items> list, int causeID, int clsID, int reportType, int year, int month, int? schoolYear, int? term, int teacherID, string schoolMark)
        {
            try
            {
                if (schoolYear == null || term == null)
                {
                    SchoolInfo school = _schoolLogic.FindBySchoolMark(schoolMark);
                    schoolYear = school.SchoolYear;
                    term = school.SchoolTerm;
                }
                StuCauseEvalList sel = _selLogic.GetEvalList(reportType, causeID, year, month, schoolYear, term, schoolMark);
                StuCauseEvalSubmitRecord ssr = GetRecordByCls(clsID, causeID, reportType, year, month, schoolYear, term, schoolMark);
                StuCauseEvalHistory sh = _shLogic.GetHistoryRecordByTerm((int)schoolYear, (int)term, causeID, schoolMark);

                // 如果德育评价记录为空，则插入一条记录
                if (sel == null)
                {
                    sel = new StuCauseEvalList();
                    sel.HistoryID = sh.RID;
                    sel.CauseID = causeID;
                    sel.StartTime = new DateTime(year, month, 1);
                    sel.Attribute = 3;

                    int selID = _selLogic.InsertStuCauseEvalEvalList(sel, schoolMark);
                    sel.RID = selID;
                }

                // 如果德育评价提交记录为空，则插入一条记录
                if (ssr == null)
                {
                    ssr = new StuCauseEvalSubmitRecord();
                    ssr.ClassID = clsID;
                    ssr.ListID = sel.RID;
                    ssr.ManagerID = teacherID;
                    ssr.Status = 1;
                    ssr.Daily = DateTime.Now;

                    int ssrID = InsertStuCauseEvalSubmitRecord(ssr, schoolMark);
                    ssr.RID = ssrID;
                }

                // 清空该班的评价和备注
                DeleteAllRecord(ssr.RID, schoolMark);
                IList<int> studentIDList = new List<int>();
                if (list == null) return true;
                Dictionary<int, double> dicMpc = new Dictionary<int, double>();
                Dictionary<DicKey, double> dicMptc = new Dictionary<DicKey, double>();
                Dictionary<DicKey, double[]> dicMpic = new Dictionary<DicKey, double[]>();
                // 保存评价和备注
                foreach (Items item in list)
                {
                    if (!string.IsNullOrEmpty(item.Remark))
                    {
                        StuCauseEvalRemark sr = new StuCauseEvalRemark();
                        sr.RecordID = ssr.RID;
                        sr.StudentID = item.StudentID;
                        sr.Data = item.Remark;
                        
                        _srLogic.InsertStuCauseEvalRemark(sr, schoolMark);
                    }
                    if (item.StuItems != null && item.StuItems.Count > 0)
                    {
                        foreach (StuItems stuItem in item.StuItems)
                        {
                            StuCauseEvalDetail sd = new StuCauseEvalDetail();
                            sd.Itemid = stuItem.MoralityItemID;
                            sd.RecordID = ssr.RID;
                            sd.StudentID = item.StudentID;
                            sd.Param = stuItem.Param;

                            _sdLogic.InsertStuCauseEvalDetail(sd, schoolMark);
                            if (!studentIDList.Contains((int)sd.StudentID)) studentIDList.Add((int)sd.StudentID);


                            #region 计算每套题目的总分

                            if (dicMpc.ContainsKey((int)sd.StudentID))
                            //if (ContainsKey(dicMpc, (int)sd.StudentID))
                            {
                                double allScore = dicMpc[(int)sd.StudentID];
                                allScore += stuItem.Type == 1 ? stuItem.Param : stuItem.Param * stuItem.Score * stuItem.Operator;
                                dicMpc[(int)sd.StudentID] = allScore;
                            }
                            else
                            {
                                dicMpc[(int)sd.StudentID] = stuItem.Type == 1 ? stuItem.Param : stuItem.Param * stuItem.Score * stuItem.Operator;
                            }

                            #endregion

                            StuCauseEvalItem si = _siLogic.GetItemByID(schoolMark, (int)sd.Itemid);
                            #region 计算每道大题的分数

                            DicKey mptcKey = new DicKey((int)sd.StudentID, (int)si.TypeID);
                            if (dicMptc.ContainsKey(mptcKey))
                            //if (ContainsKey(dicMptc, mptcKey))
                            {
                                double allScore = dicMptc[mptcKey];
                                allScore += stuItem.Type == 1 ? stuItem.Param : stuItem.Param * stuItem.Score * stuItem.Operator;
                                dicMptc[mptcKey] = allScore;
                            }
                            else
                            {
                                dicMptc[mptcKey] = stuItem.Type == 1 ? stuItem.Param : stuItem.Param * stuItem.Score * stuItem.Operator;
                            }

                            #endregion

                            #region 计算每道小题的分数

                            DicKey mpicKey = new DicKey((int)sd.StudentID, si.RID);
                            if (dicMpic.ContainsKey(mpicKey))
                            //if (ContainsKey(dicMpic, mpicKey))
                            {
                                double allScore = dicMpic[mpicKey][0];
                                double allParam = dicMpic[mpicKey][1];
                                allScore += stuItem.Type == 1 ? stuItem.Param : stuItem.Param * stuItem.Score * stuItem.Operator;
                                allParam += stuItem.Param;
                                dicMpic[mpicKey] = new double[] { allScore, allParam };
                            }
                            else
                            {
                                double allScore = stuItem.Type == 1 ? stuItem.Param : stuItem.Param * stuItem.Score * stuItem.Operator;
                                double allParam = stuItem.Param;
                                dicMpic[mpicKey] = new double[] { allScore, allParam };
                            }

                            #endregion
                        }
                    }
                }

                foreach (int studentID in studentIDList)
                {
                    // 计算缓存表

                    // 1. 将结果汇总到每张单据中每个人的总分(表:StuCausePersonCatch)
                    int recordID = ssr.RID;
                    // 先删除
                    _spcLogic.DeleteStuCausePersonCatch(studentID, recordID, schoolMark);
                    // 再插入
                    StuCausePersonCatch mpc = new StuCausePersonCatch();
                    mpc.RecordID = recordID;
                    mpc.StudentID = studentID;
                    double score = dicMpc[studentID];
                    mpc.Score = score;
                    mpc.CauseID = causeID;
                    mpc.Dirty = 0;
                    _spcLogic.InsertStuCausePersonCatch(mpc, schoolMark);

                    // 2. 将结果汇总到每张单据中每道大题每个人的得分(表:StuCausePersonTypeCatch)
                    _sptcLogic.DeleteStuCausePersonTypeCatch(studentID, recordID, schoolMark);
                    foreach (KeyValuePair<DicKey, double> dictionary in dicMptc)
                    {
                        if (dictionary.Key.StudentID != studentID) continue;
                        StuCausePersonTypeCatch mptc = new StuCausePersonTypeCatch();
                        mptc.Dirty = 0;
                        mptc.RecordID = recordID;
                        mptc.Score = dictionary.Value;
                        mptc.CauseID = causeID;
                        mptc.StudentID = studentID;
                        mptc.TypeID = dictionary.Key.ItemID;
                        _sptcLogic.InsertStuCausePersonTypeCatch(mptc, schoolMark);
                    }

                    // 3. 将结果汇总到每张单据中每道小题每个人的得分(表:StuCausePersonItemCatch)
                    _spicLogic.DeleteStuCauseEvalPersonItemCatch(studentID, recordID, schoolMark);
                    foreach (KeyValuePair<DicKey, double[]> dictionary in dicMpic)
                    {
                        if (dictionary.Key.StudentID != studentID) continue;
                        StuCauseEvalPersonItemCatch mpic = new StuCauseEvalPersonItemCatch();
                        mpic.Dirty = 0;
                        mpic.ItemID = dictionary.Key.ItemID;
                        mpic.Param = dictionary.Value[1];
                        mpic.RecordID = recordID;
                        mpic.CauseID = causeID;
                        mpic.Score = dictionary.Value[0];
                        mpic.StudentID = studentID;
                        _spicLogic.InsertStuCauseEvalPersonItemCatch(mpic, schoolMark);
                    }
                }

                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="moralitySubmitRecord"></param>
        /// <param name="schoolMark"></param>
        /// <returns></returns>
        public int InsertStuCauseEvalSubmitRecord(StuCauseEvalSubmitRecord moralitySubmitRecord, string schoolMark)
        {
            Hashtable ht = new Hashtable();
            ht.Add("StuCauseEvalSubmitRecord", moralitySubmitRecord);
            ht.Add("SchoolMark", schoolMark);
            return (int)InsertCustomer("StuCauseEvalSubmitRecord.InsertStuCauseEvalSubmitRecord", ht);
        }

        /// <summary>
        /// 清空记录
        /// </summary>
        /// <param name="recordID"></param>
        /// <param name="schoolMark"></param>
        /// <returns></returns>
        public int DeleteAllRecord(int recordID, string schoolMark)
        {
            Hashtable ht = new Hashtable();
            ht.Add("RecordID", recordID);
            ht.Add("SchoolMark", schoolMark);
            return DeleteCustomer("StuCauseEvalSubmitRecord.DeleteAllRecord", ht);
        }

        #endregion
    }
}